package com.start.workflow.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.start.workflow.common.enums.StartBaseActConfEnum;
import com.start.workflow.common.model.StartActConfigModel;
import com.start.workflow.core.mappers.StartActModelConfigMapper;
import com.start.workflow.core.service.StartActModelConfigService;
import com.start.workflow.entity.StartActModelConfig;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class StartActModelConfigServiceImpl extends ServiceImpl<StartActModelConfigMapper, StartActModelConfig> implements StartActModelConfigService {


    /**
     * 查询指定流程定义全部配置
     *
     * @param modelId
     * @return
     */
    @Override
    public List<StartActModelConfig> getActConfigsByModelId(String modelId) {
        LambdaQueryWrapper<StartActModelConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StartActModelConfig::getActModelId, modelId);
        wrapper.eq(StartActConfigModel::getProcDeployId,"");
        return list(wrapper);
    }


    /**
     * 查询指定流程模型配置
     * 返回结构为 <actType,<defKey,<confKey,StartActModelConfig>>>
     *
     * @param modelId
     * @return
     */
    @Override
    public Map<String, Map<String, Map<String, StartActModelConfig>>> getActModelConfigMapByModelId(String modelId) {
        List<StartActModelConfig> configs = getActConfigsByModelId(modelId);
        return groupActModelConfigMap(configs);
    }


    /**
     * 删除最新的流程模型配置
     *
     * @param modelId 模型id
     */
    @Override
    public void removeByModelId(String modelId) {
        LambdaQueryWrapper<StartActModelConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StartActModelConfig::getActModelId, modelId);
        wrapper.eq(StartActModelConfig::getProcDeployId, "");
        remove(wrapper);
    }

    @Override
    public List<StartActModelConfig> getActModelConfigs(String deployId, StartBaseActConfEnum actType) {
        Wrapper<StartActModelConfig> modelConfigQuery = createModelConfigQuery(deployId, actType);
        return list(modelConfigQuery);
    }

    @Override
    public long getActModelConfigCount(String deployId, StartBaseActConfEnum actType) {
        Wrapper<StartActModelConfig> modelConfigQuery = createModelConfigQuery(deployId, actType);
        return count(modelConfigQuery);
    }

    private Wrapper<StartActModelConfig> createModelConfigQuery(String deployId, StartBaseActConfEnum actType) {
        LambdaQueryWrapper<StartActModelConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StartActModelConfig::getProcDeployId, deployId);
        if (actType != null) {
            wrapper.eq(StartActModelConfig::getActType, actType.getActType());
        }
        return wrapper;
    }

    /**
     * 查询指定发布id， 的全部配置并分组
     *
     * @param deployId
     * @return
     */

    @Override
    public Map<String, Map<String, Map<String, StartActModelConfig>>> getActModelConfigMap(String deployId) {
        List<StartActModelConfig> modelConfigs = getActModelConfigs(deployId);
        return groupActModelConfigMap(modelConfigs);
    }

    private Map<String, Map<String, Map<String, StartActModelConfig>>> groupActModelConfigMap(List<StartActModelConfig> modelConfigs) {
        if (modelConfigs == null) return new HashMap<>();
        Map<String, Map<String, Map<String, StartActModelConfig>>> result = new HashMap<>();
        for (StartActModelConfig config : modelConfigs) {
            String actType = config.getActType();
            String procDefKey = config.getProcDefKey();
            String confType = config.getConfType();
            if (!result.containsKey(actType)) {
                result.put(actType, new HashMap<>());
            }
            Map<String, Map<String, StartActModelConfig>> defKeyMap = result.get(actType);
            if (!defKeyMap.containsKey(procDefKey)) {
                defKeyMap.put(procDefKey, new HashMap<>());
            }
            Map<String, StartActModelConfig> confTypeMap = defKeyMap.get(procDefKey);
            confTypeMap.put(confType, config);
        }
        return result;
    }

    /**
     * 查询指定发布id，指定actType的全部配置并分组
     * 返回结构为  <defKey,<confType,StartActModelConfig>>
     *
     * @param deployId
     * @param actType
     * @return
     */
    @Override
    public Map<String, Map<String, StartActModelConfig>> getActModelConfigMap(String deployId, StartBaseActConfEnum actType) {
        List<StartActModelConfig> modelConfigs = getActModelConfigs(deployId, actType);
        if (modelConfigs == null) return new HashMap<>();
      Map<String, Map<String, StartActModelConfig>> result = new HashMap<>();
        for (StartActModelConfig config : modelConfigs) {
            String procDefKey = config.getProcDefKey();
            String confType = config.getConfType();
            if (!result.containsKey(procDefKey)) {
                result.put(procDefKey, new HashMap<>());
            }
            Map<String, StartActModelConfig> confTypeMap = result.get(procDefKey);
            confTypeMap.put(confType, config);
        }
        return result;
    }

    @Override
    public Map<String, StartActModelConfig> getActModelActTypeConfigMap(String deployId, StartBaseActConfEnum actType) {
        LambdaQueryWrapper<StartActModelConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StartActModelConfig::getProcDeployId, deployId);
        wrapper.eq(StartActModelConfig::getActType, actType.getActType());
        wrapper.eq(StartActModelConfig::getConfType, actType.getValue());
        List<StartActModelConfig> list = list(wrapper);
        return list.stream().collect(Collectors.toMap(StartActModelConfig::getProcDefKey, e -> e));
    }

    /**
     * 获取模型配置
     *
     * @param deploymentId 流程发布id
     * @param defKey       定义key
     * @param actType
     * @return
     */
    @Override
    public StartActModelConfig getActModelConfig(String deploymentId, String defKey, StartBaseActConfEnum actType) {
        LambdaQueryWrapper<StartActModelConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StartActModelConfig::getProcDeployId, deploymentId);
        wrapper.eq(StartActModelConfig::getActType, actType.getActType());
        wrapper.eq(StartActModelConfig::getProcDefKey, defKey);
        wrapper.eq(StartActModelConfig::getConfType, actType.getValue());
        return getOne(wrapper, false);
    }
}
